using System.Reflection;
using Crux.Core.EasyNetQ;
using Crux.Core.Reflections;
using Microsoft.Extensions.DependencyInjection;

namespace System;
/// <summary>
/// EasyNetQServiceProviderExtensions
/// </summary>
public static class EasyNetQServiceProviderExtensions
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="serviceProvider"></param>
    /// <param name="subscriptionIdPrefix"></param>
    /// <param name="consumerTypes"></param>
    /// <returns></returns>
    public static IServiceProvider UseEasyNetQ(
        this IServiceProvider serviceProvider,
        string subscriptionIdPrefix,
        params Type[] consumerTypes)
    {
        serviceProvider.GetRequiredService<EasyNetQInitializer>()
                               .InitAutoSubscriber(subscriptionIdPrefix,
                                                   serviceProvider.GetRequiredService<IAutoSubscriberMessageDispatcher>(),
                                                   consumerTypes);
        return serviceProvider;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="serviceProvider"></param>
    /// <param name="subscriptionIdPrefix"></param>
    /// <returns></returns>
    public static IServiceProvider UseEasyNetQ(
        this IServiceProvider serviceProvider,
        string subscriptionIdPrefix)
    {
        var typeFinder = new TypeFinder(new AssemblyFinder());

        var types = typeFinder.Find(type =>
        {
            var typeInfo = type.GetTypeInfo();

            var interfaces = typeInfo.GetInterfaces();
            return interfaces.Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IConsumeAsync<>));
        });

        serviceProvider.GetRequiredService<EasyNetQInitializer>().InitAutoSubscriber(
            subscriptionIdPrefix,
            serviceProvider.GetRequiredService<IAutoSubscriberMessageDispatcher>(),
            types);

        return serviceProvider;
    }
}